package org.fuys.coder.domain.search.service.impl;

import org.fuys.coder.common.constants.ResultMessageConstants;
import org.fuys.coder.common.entity.Pair;
import org.fuys.coder.common.exception.BusinessException;
import org.fuys.coder.common.util.BitOperationUtil;
import org.fuys.coder.domain.category.model.vo.CategoryVO;
import org.fuys.coder.domain.category.service.ICategoryService;
import org.fuys.coder.domain.search.model.req.SearchReq;
import org.fuys.coder.domain.search.model.vo.AllSearchVO;
import org.fuys.coder.domain.search.model.vo.SearchResultVO;
import org.fuys.coder.domain.search.model.vo.SearchTypeVO;
import org.fuys.coder.domain.search.service.ISearchService;
import org.fuys.coder.domain.substance.model.vo.SubstanceVO;
import org.fuys.coder.domain.substance.service.repo.ISubstanceService;
import org.fuys.coder.domain.user.model.vo.repo.AuthorVO;
import org.fuys.coder.domain.user.service.repo.IUserService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @projectName: fuys-low-coder
 * @package: org.fuys.coder.domain.search.service.impl
 * @className: SearchServiceImpl
 * @author: WangJing
 * @description: 搜索服务实现类
 * @date: 2024/8/15 17:23
 * @version: 1.0
 */
@Service
public class SearchServiceImpl implements ISearchService {

    @Resource
    private ISubstanceService substanceService;

    @Resource
    private IUserService userService;

    @Resource
    private ICategoryService categoryService;

    @Override
    public SearchResultVO<SubstanceVO> searchSubstance(SearchReq searchReq) {
        if(ObjectUtils.isEmpty(searchReq.getType())||!(searchReq.getType().equals(SearchTypeVO.SUBSTANCE))){
            return null;
        }
        final String keywords = searchReq.getKeywords();
        List<SubstanceVO> substanceList=substanceService.getSubstanceByName(searchReq.getPageDTO(),keywords);
        if(substanceList==null){
            return null;
        }
        SearchResultVO<SubstanceVO> resultVO=new SearchResultVO<>();
        Pair<String,List<SubstanceVO>> resultMap=new Pair<>(SearchTypeVO.getType(searchReq.getType()),substanceList);
        resultVO.setResultMap(resultMap);
        return resultVO;
    }

    @Override
    public SearchResultVO<AuthorVO> searchAuthor(SearchReq searchReq) {
        if(ObjectUtils.isEmpty(searchReq.getType())||!(searchReq.getType().equals(SearchTypeVO.AUTHOR))){
            return null;
        }
        final String keywords = searchReq.getKeywords();
        final Pair<List<AuthorVO>, Long> authorVOsPageByName = userService.getAuthorVOsPageByName(searchReq.getPageDTO(), keywords);
        if(authorVOsPageByName==null){
            return null;
        }
        SearchResultVO<AuthorVO> resultVO=new SearchResultVO<>();
        Pair<String,List<AuthorVO>> resultMap=new Pair<>(SearchTypeVO.getType(searchReq.getType()),authorVOsPageByName.getLeft());
        resultVO.setResultMap(resultMap);
        resultVO.setTotal(authorVOsPageByName.getRight());
        return resultVO;
    }

    @Override
    public SearchResultVO<CategoryVO> searchCategory(SearchReq searchReq) {
        if(ObjectUtils.isEmpty(searchReq.getType())||!(searchReq.getType().equals(SearchTypeVO.CATEGORY))){
            return null;
        }
        final String keywords = searchReq.getKeywords();
        List<CategoryVO> categoryVOS = categoryService.getCategoryByName(searchReq.getPageDTO(),keywords);
        if(categoryVOS==null){
            return null;
        }
        SearchResultVO<CategoryVO> resultVO=new SearchResultVO<>();
        Pair<String,List<CategoryVO>> resultMap=new Pair<>(SearchTypeVO.getType(searchReq.getType()),categoryVOS);
        resultVO.setResultMap(resultMap);
        return resultVO;
    }

    @Override
    public SearchResultVO<AllSearchVO> searchMultiple(SearchReq searchReq) {
        //todo 或许可以动态配置 而不是写死？
        final Integer multiple = searchReq.getMultiple();
        if(ObjectUtils.isEmpty(multiple)||searchReq.getType()!=null){
            return null;
        }
        if(multiple >SearchTypeVO.MAX_VALUE){
            throw new BusinessException(ResultMessageConstants.ILLEGAL_DATA_FORMAT+"请指定搜索类型");
        }
        AllSearchVO searchVO=new AllSearchVO();
        final long longBit = multiple.longValue();
        if (BitOperationUtil.getLongBit(longBit,0)) {
            searchReq.setType(SearchTypeVO.SUBSTANCE);
            final SearchResultVO<SubstanceVO> substanceVOSearchResultVO = searchSubstance(searchReq);
            if(substanceVOSearchResultVO!=null)
            searchVO.getVoMap().put(SearchTypeVO.getType(SearchTypeVO.SUBSTANCE),substanceVOSearchResultVO);
        }
        if(BitOperationUtil.getLongBit(longBit,1)){
            searchReq.setType(SearchTypeVO.AUTHOR);
            final SearchResultVO<AuthorVO> resultVO = searchAuthor(searchReq);
            if(resultVO!=null)
            searchVO.getVoMap().put(SearchTypeVO.getType(SearchTypeVO.AUTHOR),resultVO);
        }
        if(BitOperationUtil.getLongBit(longBit,2)){
            searchReq.setType(SearchTypeVO.CATEGORY);
            final SearchResultVO<CategoryVO> resultVO = searchCategory(searchReq);
            if(resultVO!=null)
            searchVO.getVoMap().put(SearchTypeVO.getType(SearchTypeVO.CATEGORY),resultVO);
        }
        SearchResultVO<AllSearchVO> resultVO=new SearchResultVO<>();
        //todo 可以给广告拓展 这里就暂时不进行了 直接使用单例列表来设置返回
//        List<AllSearchVO> allSearchVOS=new ArrayList<>();
        resultVO.setResultMap(new Pair<String, List<AllSearchVO>>("multiple", Collections.singletonList(searchVO)));
        return resultVO;
    }
}
